package com.swyc.osschat.Test.Jinzhi;

/**
 * @description 进制转换（计算机中存储数据的时候都是按照补码的形式存进去的）
 * 正数的原码，反码，补码都一样，负数的原码，反码，补码都不一样，负数在存储的时候存进去的是补码。
 * 什么是原码？就是符号位+数值位（数据的绝对值）
 * 什么是反码：反码就是符号位不变，其他位全部0变1，1变0；
 * 什么是补码：补码就是在反码的基础上+1就是补码
 * 转十进制：
 *  需要理解的参数：
 *      系数：每一位上的数据
 *      基数：N进制的基数就是N
 *      权：从右往左的数据开始数，第一位是0，第二位是1，第三位是2，依次数，0，1，2就是该位的权
 *  规律：任意进制到十进制的转换都等于这个数据各个位上的系数乘以基数的权次幂相加的和
 *  例如：二进制0b110转十进制：0*2^0+1*2^1+1*2^2 = 6
 * 十进制转任意进制：
 *  规律：除以基数取余数，知道商为0，余数反转；
 *  例如：十进制100转二进制：0b1100100
 * 十进制和二进制之间的快速转换
 *  8421码：
 *      二进制：    1       1       1       1       1       1       1       1
 *      十进制：    128     64      32      16      8       4       2       1
 *  例如：二进制0b11011转十进制：1+2+0+8+16=27
 *       十进制110转二进制：64+32+8+4+2=110 所以二进制应该是0b1101110
 * 位运算：
 *  &：按位与
 *      规则：两个数据同权位的数据都是1的时候才是1
 *  |：按位或
 *      规则：两个数据同权位的数据只要有一个是1那就是1
 *  ^：按位异或
 *      规则：两个数据同权位的数据都不一样的时候为1结果一样就是0
 *      使用：1.加密运算，3 ^ 4 ^ 4 = 3 异或两次的时候还是第一个数
 *           2.实现两个变量值的交换，并且不能使用第三个变量
 *           例如：int a=10; b=20;
 *           实现交换：
 *           a=a^b
 *           b=a^b  可以根据第一个等式看成：b=a^b^b 实现了a给b数值
 *           a=a^b  可以根据第二个等式看成：a=a^a^b 实现了b给a数值
 *           这样就实现了交换
 *  ~：按位取反
 *      规则：两个数据同权位的数据只要有一个是1那就是1
 *  <<：左移
 *      规则：让操作数乘以2的N次幂，N就是移动的位数
 *  >>：右移
 *      规则：让操作数除以2的N次幂，N就是移动的位数
 *  >>>：无符号右移
 *      规则：
 *  位运算符连接的操作数是什么？数值类型（二进制）
 *  位运算表达式的结果是什么？数值类型
 *  3 & 4 结果是多少？
 *  在进行位运算的时候要把数据转换成二进制位，并且全都是二进制补码的形式！
 *  3的二进制：0b00000000000000000000000000000011
 *  4的二进制：0b00000000000000000000000000000100
 *  3 & 4 = 0b00000000000000000000000000000000
 *  3 | 4 结果是多少？
 *  在进行位运算的时候要把数据转换成二进制位，并且全都是二进制补码的形式！
 *  3的二进制：0b00000000000000000000000000000011
 *  4的二进制：0b00000000000000000000000000000100
 *  3 | 4 = 0b00000000000000000000000000000111
 *  3 ^ 4 结果是多少？
 *  在进行位运算的时候要把数据转换成二进制位，并且全都是二进制补码的形式！
 *  3的二进制：0b00000000000000000000000000000011
 *  4的二进制：0b00000000000000000000000000000100
 *  3 ^ 4 = 0b00000000000000000000000000000111
 *  3 ~ 4 结果是多少？
 *  在进行位运算的时候要把数据转换成二进制位，并且全都是二进制补码的形式！
 *  3的二进制：0b00000000000000000000000000000011
 *  ~3取反结果：0b11111111111111111111111111111100   补码  负数
 *  补码：   0b11111111111111111111111111111100
 *  -                                        1
 *  ---------------------------------------------
 *          0b11111111111111111111111111111011
 *  取反：0b10000000000000000000000000000100
 *
 * @Author: z156940l@outlook.com
 * @className Test
 * @Date: 2023/2/23 15:28
 */
public class Test {
    public static void main(String[] args) {
        int a = 0b11111111111111111111111111100000;
        System.out.println(a);
        System.out.println("------------------------二进制到十进制-----------------------");
        int b = 0144;
        System.out.println(b);
        System.out.println("------------------------八进制到十进制-----------------------");
        int c = 0110;
        System.out.println(c);
        System.out.println("------------------------八进制到十进制-----------------------");
        int d = 0x64;
        System.out.println(d);
        System.out.println("------------------------十六进制到十进制-----------------------");
        int e = 3 & 4;
        System.out.println(e);
        System.out.println("------------------------3 & 4------------------------");
        int f = 3 | 4;
        System.out.println(f);
        System.out.println("------------------------3 | 4------------------------");
        int g = 3 ^ 4 ;
        System.out.println(g);
        System.out.println("------------------------3 ^ 4------------------------");
        int h = ~3;
        System.out.println(h);
        System.out.println("------------------------~3------------------------");
        int yha = 10;
        int yhb = 20;
        yha = yha ^ yhb;
        yhb = yha ^ yhb;
        yha = yha ^ yhb;
        System.out.println("yha:"+yha);
        System.out.println("yhb:"+yhb);
        System.out.println("------------------------不创建第三个变量实现两个变量的交换------------------------");
        int i;
        i = 3 << 2;  //操作数 3 * 2 ^ 2 = 12
        /**
         * 3 << 2
         * 3的二进制位：0b00000000000000000000000000000011
         * 往左边移动两位，右边就空出两位，左边移动的两位就被挤掉了，右边空出的两位就用0补全：0b00000000000000000000000000001100
         */
        System.out.println(i);
        System.out.println("------------------------<<------------------------");
        int j;
        j = -32 >> 2;  //操作数 3 * 2 ^ 2 = 12
        /**
         * 32 >> 2
         * 32的二进制位：0b00000000000000000000000000100000
         * 往右边移动两位，左边就空出两位，右边移动的两位就被挤掉了，左边空出的两位就用符号位补全（符号位是1就用1填充，符号位是0就用0填充）：0b00000000000000000000000000001000
         * 如果是：-32 >> 2
         * -32的二进制位：10000000000000000000000000100000
         *         反码：11111111111111111111111111011111
         *         补码：11111111111111111111111111100000
         *         -32往右移动两位：11111111111111111111111111111000
         *         补码求原码：11111111111111111111111111111000
         *         -                                          1
         *         ----------------------------------------------
         *       反码：       11111111111111111111111111110111
         *       原码：       10000000000000000000000000001000
         */
        System.out.println(j);
        System.out.println("------------------------>>------------------------");
        int k;
        /**
         * -32的二进制位
         *      原码：10000000000000000000000000100000
         *      反码：11111111111111111111111111011111
         *      补码：11111111111111111111111111100000
         *      无符号右移之后：00111111111111111111111111111000
         *      结论：无符号右移如果是操作的一个整数，那么和右移的结果是一样的，如果操作的是一个负数，结果会变成一个正数
         */
        k = -32 >>> 2;
        System.out.println(k);
        System.out.println("------------------------>>>------------------------");
    }
}
